package com.qire.common.concurrent;

import android.os.Handler;
import android.os.Looper;

import com.qire.antscore.common.AntsThreadBuilder;
import com.qire.antscore.common.AntsThreadBuilder.AntsThreadFactory;
import com.qire.common.function.TaskAction;

/**
 * 调度器
 */
public abstract class Scheduler {

    /** 同步回到第一个调度线程调度 */
    public static final Scheduler Sync = new SyncScheduler();
    /** 异步新开一个调度线程调度 */
    public static final Scheduler Async = new AsyncScheduler();
    /** 主线程调度 */
    public static final Scheduler Main= new HandlerScheduler();

    /**
     * @return true 是同步的,在上一个调度线程中运行，false 非同步的，会调度到新线程运行
     */
    public abstract boolean isSync();

    /**
     * 调度执行任务
     * @param taskAction 任务处理程序
     * @param t 传递数据
     * @param <T> 传递数据类型
     */
    public abstract <T> void scheduler(final TaskAction<T> taskAction, T t);

    /**************************************************************************************************************/

    private static class SyncScheduler extends Scheduler {
        @Override
        public boolean isSync() {
            return true;
        }

        @Override
        public <T> void scheduler(final TaskAction<T> taskAction, T t) {
            taskAction.accept(t);
        }
    }

    private static class AsyncScheduler extends Scheduler {
        AntsThreadFactory antsThreadFactory = AntsThreadBuilder.newAntsThreadFactory("AsyncScheduler");

        @Override
        public boolean isSync() {
            return false;
        }

        @Override
        public <T> void scheduler(final TaskAction<T> taskAction, T t) {
            antsThreadFactory.newThread(() -> {
                taskAction.accept(t);
                taskAction.notifyNext();
            }).start();
        }
    }

    // todo 临时调整，一个彻底改成RX方式。在来做调度
    public static class HandlerScheduler extends Scheduler {
        public final Handler handler = new Handler(Looper.getMainLooper());

        @Override
        public boolean isSync() {
            return false;
        }

        @Override
        public <T> void scheduler(final TaskAction<T> taskAction, T t) {
            handler.post(() -> {
                taskAction.accept(t);
                taskAction.notifyNext();
            });
        }
    }

}
